import axios from 'axios'

class OssUploader {
  /**
   * OSS 上传工具类
   * @param {Object} config 配置项
   * @param {Function} config.getPolicy 获取OSS凭证的方法
   * @param {Function} [config.generateFileName] 自定义文件名生成方法
   * @param {Object} [config.headers] 自定义请求头
   */
  constructor(config) {
    if (!config.getPolicy) throw new Error('Missing required getPolicy function')
    this.getPolicy = config.getPolicy
    this.generateFileName = config.generateFileName || this.defaultGenerateFileName
    this.headers = config.headers || { 'Content-Type': 'multipart/form-data' }
  }

  /**
   * 默认文件名生成方法
   * @param {File} file 文件对象
   * @returns {string} 生成的文件名
   */
  defaultGenerateFileName(file) {
    const fileExtension = file.name.split('.').pop()
    return `${Date.now()}_${Math.random().toString(36).slice(2, 8)}.${fileExtension}`
  }

  /**
   * 执行文件上传
   * @param {File} file 要上传的文件
   * @param {string} dir OSS存储目录
   * @returns {Promise<{url: string, key: string}>} 上传结果
   */
  async upload(file, dir) {
    try {
      // 获取OSS凭证
      const policyRes = await this.getPolicy()
      if (policyRes.code !== 200) {
        throw new Error('Failed to get OSS policy')
      }

      const ossData = policyRes.data
      const filename = this.generateFileName(file)
      const key = `${ossData.dir || dir}${filename}`

      // 构造表单数据
      const formData = new FormData()
      formData.append('key', key)
      formData.append('OSSAccessKeyId', ossData.accessid)
      formData.append('policy', ossData.policy)
      formData.append('Signature', ossData.signature)
      formData.append('file', file)

      // 执行上传
      const uploadRes = await axios.post(ossData.host, formData, {
        headers: this.headers
      })

      if (uploadRes.status === 204) {
        return {
          url: `${ossData.host}/${key}`,
          key: key
        }
      }
      throw new Error('Upload failed with unexpected status')
    } catch (error) {
      throw new Error(`Upload failed: ${error.response?.data?.message || error.message}`)
    }
  }
}

export default OssUploader
